package com.opcode.nebulamobil.base.activities;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;

import com.opcode.nebulamobil.base.fragments.dialogfragments.DialogFragmentBase;
import com.opcode.nebulamobil.base.fragments.dialogfragments.TwoButtonDialogFragmentBase;
import com.opcode.nebulamobil.base.interfaces.ConnectionListener;
import com.opcode.nebulamobil.enums.TwoButtonDialogType;
import com.opcode.nebulamobil.information.ApplicationInfo;
import com.opcode.nebulamobil.information.dataforms.costadataforms.ConnectionStatus;
import com.opcode.nebulamobil.information.dataforms.costadataforms.ConnectionStatus.ConnectionStatusInfo;
import com.opcode.nebulamobil.information.requests.costarequests.ActivationReq;
import com.opcode.nebulamobil.utility.JsonConverter;
import com.opcode.nebulamobil.utility.STSLog;
import com.opcode.nebulamobil.utility.UniqueIdCreator;

/**
 * Bu aktivite, Nebula Mobil'de yer alan bütün aktivitelerin üst sınıfını oluşturur.
 * Aktivitelerin her birinde yer alan ortak fonksiyonlar bu sınıf tarafından yönetilir.
 * @author Okan ERDOĞAN
 * 8 Eyl 2014
 */
public abstract class FragmentActivityBase extends FragmentActivity implements ConnectionListener{
	
	public FragmentManager fragmentManager = null;
	private String fileName;
	private String macAddress;
	private SharedPreferences aData = null;
	private static FragmentActivityBase fragmentActivityBase;

	/**
	 * Uygulamanın çalıştırılması esnasında yaşam döngüsünde ilk çalışacak yer burasıdır.
	 * Bu metod içerisinde uygulamanın dik olarak kullanılacağı belirtilir.
	 * Ayrıca fragment'ların yönetiminde kullanılacak olan fragmentManager nesnesi elde edilir.
	 */
	protected void onCreate(Bundle savedInstanceState) {
		
		/*
		 * Uygulamada hiçkimse tarafından yakalanmayan hatalar bu metod sayesinde yakalanırlar.
		 */
		/*Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
	    {
	      @Override
	      public void uncaughtException (Thread thread, Throwable e)
	      {
	    	  
	      }
	    });*/
		
	   super.onCreate(savedInstanceState);
	   
	   /*
	    * Ekranın dik olarak kullanılmasını ve ekranın sürekli açk kalmasını sağlayan ayarlar yapılıyor.
	    */
	   this.getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON);		
       this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
	   this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

	   /*
	    * FragmentManager nesnesi üst sınıftan elde ediliyor.
	    */
	   this.fragmentManager = super.getSupportFragmentManager();
	}
	
	
	
	
	
	/**
	 * Yaşam döngüsünde onStart'tan ve onPause'dan sonr çalışan metoddur.
	 */
	public void onResume(){
		super.onResume();
		
		ApplicationInfo.setConnectionListener(this);
	}
	
	
	
	//-----------------SUBFRAGMENT METODLARI---------------
	/**
	 * Parametre olarak verilen fragment nesnesi yine parametre olarak verilen view'a eklenir.
	 * @param viewContainerId
	 * @param selectionFragment
	 */
	public void subFragmentAddToContainer(int viewContainerId, Fragment selectionFragment){
		FragmentManager fragmentManager = getSupportFragmentManager();		
		FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();		
		fragmentTransaction.add(viewContainerId, selectionFragment);
		fragmentTransaction.show(selectionFragment);		
		fragmentTransaction.commit();
	}
	//-----------------SUBFRAGMENT METODLARI---------------

	
	
	
	
	
	
	
	
	
	//-----------------BAĞLANTI KONTROL METODLARI-----------------
	/**
	 * Internet bağlantısının var olup olmadığını kontrol eder.
	 * @return
	 */
	public boolean isNetworkAvailable() {
	    ConnectivityManager connectivityManager = (ConnectivityManager)this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
	    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
	    return activeNetworkInfo != null;
	}
	//-----------------BAĞLANTI KONTROL METODLARI-----------------
	
	
	
	
	
	
	
	
	
	//--------------SHARED PREFERENCES METODLARI--------------------
	/**
	 * Bir sharedPreferences nesnesi elde etmek için kullanılan metoddur.
	 * Bu metod neticesinde elde edilen aData nesnesi ile uygulamada baz� veriler sharedPreferences içine kayıt edilebilir.
	 * Bu projede sharedPreferences'a kayıt edilen verilen varsayılan olarak başka uygulamaların erişimine kapatılmıştır.
	 * Ancak istenirse bu veriler herkese açık hale getirilebilir.
	 * @param fileName
	 * @param context
	 */
	public void createSharedPreferencesManager(String fileName,Context context){
		this.fileName=fileName;
		this.aData= context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
	}
	
	
	/**
	 * Parametre olarak verilen key ve value verilerine göre sharedPreferences'a veri kaydetmek için kullanılır.
	 * @param key
	 * @param value
	 */
	public void writeToSharedPreferences(String key,boolean value){
		SharedPreferences.Editor prefEditor = aData.edit();
        prefEditor.putBoolean(key, value);
        prefEditor.commit();
	}
	
	
	/**
	 * SharedPreferences'a bir key ile kayıt edilen verileri yine aynı key ile elde etmeyi sağlar.
	 * Bu metodun geri dönüş tipi boolean'dır.
	 * @param key
	 * @param defValue
	 * @return
	 */
	public boolean readFromSharedPreferences(String key,boolean defValue){
		boolean value=aData.getBoolean(key, defValue);
		return value;
	}
	
	
	/**
	 * String tipindeki verilerin sharedPreferences'a kayıt edilmesini sağlayan metoddur.
	 * @param key
	 * @param value
	 */
	public void writeToSharedPreferences(String key,String value){
		SharedPreferences.Editor prefEditor = aData.edit();
        prefEditor.putString(key, value);
        prefEditor.commit();
	}
	
	
	/**
	 * String tipindeki verilerin sharedPreferences'tan elde edilmesini sağlayan metoddur.
	 * @param key
	 * @param defValue
	 * @return
	 */
	public String readFromSharedPreferences(String key,String defValue){
		try{
			String value=aData.getString(key, defValue);
			return value;
		}catch(NullPointerException exception){
			STSLog.writeLog(exception,this.getClass().getCanonicalName(),"SharedPreferences nesnesi bulunamadı.");										
			return null;
		}
	}
	//--------------SHARED PREFERENCES METODLARI--------------------

	
	
	
	//---------------------DİALOG AÇMA VE KAPAMA METODLARI------------
	/**
	 * Ekrandan bağımsız olarak açılabilecek olan dialogları yönetir.
	 */
	public void showGeneralDialog(DialogFragmentBase dialogFragment,String dialogTag){
		try{
			FragmentManager fragmentManager = getSupportFragmentManager();
			
			dialogFragment.setCancelable(false);
		
			if(!dialogFragment.isAdded()){
				dialogFragment.show(fragmentManager, dialogTag);
			}
		}catch(IllegalStateException exception){
			STSLog.writeLog(exception,this.getClass().getCanonicalName(),dialogTag+" hali hazırda eklenmişti.");												
		}
	}
	
	
	/**
	 *	Ekrandan bağımsız olarak açılabilecek olan dialogları kapatır.
	 */
	public void closeGeneralDialog(DialogFragmentBase dialogFragment,String dialogTag){
		
		try{
			if(dialogFragment!=null){
				try {
					Thread.sleep(1000);
					if(dialogFragment!=null &&  dialogFragment.getDialog()!=null&& dialogFragment.getDialog().isShowing()) {
						dialogFragment.dismiss();
					}
				} catch (InterruptedException e) {
					STSLog.writeLog(e,this.getClass().getCanonicalName(),"Thread beklenmeyen bir şekilde durdu.");														
				}
			}
		}catch(IllegalStateException exception){			
			STSLog.writeLog(exception,this.getClass().getCanonicalName(),"Acitivty'nin durumu kayıt edildikten sonra işlem yapılmak istendi.");														
		}
		
	}
	//---------------------DİALOG AÇMA VE KAPAMA METODLARI------------

	
	
	/**
	 * 
	 * @return
	 */
	public boolean checkActivasion(){

		WifiManager manager = (WifiManager) this.getSystemService(this.WIFI_SERVICE);
		WifiInfo info = manager.getConnectionInfo();
		macAddress = info.getMacAddress();
		String versionName="0.0";
		int versionCode=0;
		PackageInfo pInfo;
		String brand = Build.BRAND;
		String model = Build.MODEL;
		try {
			pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
			versionName = pInfo.versionName;
			versionCode=pInfo.versionCode;
			System.out.println();

		} catch (NameNotFoundException e) {
			STSLog.writeLog(e,this.getClass().getCanonicalName(),"Paket ismi bulunamadı.");														
		}
		
		ActivationReq activasionReq=new ActivationReq();
		activasionReq.setDeviceMacAddress(macAddress);
		activasionReq.setVersionCode(versionCode);
		activasionReq.setVersionName(versionName);
		
		activasionReq.setDeviceType(brand+" "+model);
		if(ApplicationInfo.isTablet()){
			activasionReq.setAppType("CostaKitchenTerminal");
		}else{
			activasionReq.setAppType("CostaHandTerminal");
		}
		activasionReq.setType("ActivationReq");
		activasionReq.setRequestId(UniqueIdCreator.createUniqueID());
		
		ApplicationInfo.getRequestListener().jsonRequestCame(JsonConverter.toJsonString(activasionReq));
		return true;
	}
	
	
	
	
	@Override
	public void connectionStatusChanged(ConnectionStatus status) {
		if (status.getConnectionStatusInfo().equals(ConnectionStatusInfo.CONNECTED)) {
			checkActivasion();
		} else if (status.getConnectionStatusInfo().equals(ConnectionStatusInfo.CONNECTION_LOST)) {
			if(fragmentActivityBase!=null){
				Intent defaultActivityIntent=new Intent(this,fragmentActivityBase.getClass());
				defaultActivityIntent.putExtra("erroroccured", true);
				startActivity(defaultActivityIntent);
			}else{
				showGeneralDialog(new TwoButtonDialogFragmentBase(status.getConnectionInfoMessage(),TwoButtonDialogType.CONNECTION_LOST_DIALOG), "GENERAL_TWO_BUTTON_DIALOG");
			}
				
				
		} else if (status.getConnectionStatusInfo().equals(ConnectionStatusInfo.SERVER_NOT_FOUND)) {
			if(fragmentActivityBase!=null){
				Intent defaultActivityIntent=new Intent(this,fragmentActivityBase.getClass());
				defaultActivityIntent.putExtra("erroroccured", true);
				startActivity(defaultActivityIntent);
			}else{
				showGeneralDialog(new TwoButtonDialogFragmentBase(status.getConnectionInfoMessage(),TwoButtonDialogType.CONNECTION_LOST_DIALOG), "GENERAL_TWO_BUTTON_DIALOG");
			}
		}
	}
	
	
	/**
	 * Uygulamada beklenmeyen bir durum meydana geldiğinde yeniden başlatma esnasında varsayılan olarak açılacak olan ekranı belirlemeye yarayan metoddur.
	 * @param fragmentActivityBase
	 */
	public void setDefaultStartActivity(FragmentActivityBase fragmentActivityBase){
		this.fragmentActivityBase=fragmentActivityBase;
	}
	
	
	
	
}
